import { _decorator, Component, Node, director, DirectorEvent, UIRenderer, ScrollView, Mask, UITransform, math, rect } from 'cc';
import { JSB } from 'cc/env';
import { Main } from './Main';
import { MergeItem } from './MergeItem';
const { ccclass, property } = _decorator;

@ccclass('MergeRoot')
export class MergeRoot extends Component {

    static emptyArray: any[] = [];

    oldChildren: Node[] = [];

    static bMergeItem: boolean = true;

    hasPrintLevelChildrenLen: boolean = false;

    newChildrenArray:Node[] = [];

    levelChildrenArray:any[] = [];

    onLoad() {
    }

    onEnable() {
        director.on(DirectorEvent.BEFORE_DRAW, this.onBeforeDraw, this);
        director.on(DirectorEvent.AFTER_DRAW, this.onAfterDraw, this);
    }

    onDisable() {
        director.off(DirectorEvent.BEFORE_DRAW, this.onBeforeDraw, this);
        director.off(DirectorEvent.AFTER_DRAW, this.onAfterDraw, this);
    }

    onBeforeDraw() {

        if (!MergeRoot.bMergeItem) {
            return;
        }

        const children = this.oldChildren = this.node.children;

        if (!children?.length) {
            return;
        }

        // let newChildren = [];
        // let levelChildrenArr = [];

        let newChildren = this.newChildrenArray;
        newChildren.length = 0;
        let levelChildrenArr = this.levelChildrenArray;
        levelChildrenArr.length = 0;

        for (const c of children) {
            const comp = c["mergeItem"] as MergeItem;
            if (!comp) {
                return;
            }
            const ret = this.checkCulling(comp);
            if (!ret) {
                continue;
            }
            levelChildrenArr.push(comp.levelChildren);
        }

        let itemLength = levelChildrenArr.length; //多少个item

        if (!this.hasPrintLevelChildrenLen) {
            this.hasPrintLevelChildrenLen = true;
            console.log(" total children render count ... " + itemLength);
        }


        let levelLength = 0//levelChildrenArr[0].length; //多少层

        for (let i = 0, len = levelChildrenArr.length; i < len; i++) {
            let tempLen = levelChildrenArr[i].length;
            if (tempLen > levelLength) {
                levelLength = tempLen;
            }
        }


        for (let levIndex = 0; levIndex < levelLength; levIndex++) {//第几层

            //下面这行有bug，每一层的数量可能不一样
            let curLevLength = 0 //levelChildrenArr[0][levIndex].length;
            //找到每一层的最大数目
            for (let z = 0; z < itemLength; z++) {
                let levLength = levelChildrenArr[z][levIndex]?.length;
                if (levLength > curLevLength) {
                    curLevLength = levLength;
                }
            }

            for (let y = 0; y < curLevLength; y++) { //每层的第几个
                for (let z = 0; z < itemLength; z++) { //第几个levelChildren
                    const renderChild = levelChildrenArr[z] && levelChildrenArr[z][levIndex] && levelChildrenArr[z][levIndex][y];
                    !!renderChild
                        && renderChild.active
                        // && !!renderChild.getComponent(UIRenderer) 
                        !! renderChild["hasUIRenderer"] 
                        && newChildren.push(renderChild);
                        // && (renderChild.getComponent(UIRenderer) && (!renderChild.getComponent(ScrollView) && !renderChild.getComponent(Mask)))
                        // && renderChild["hasUIRenderer"] 
                       (!renderChild["hasScrollView"]
                            && !renderChild["hasMask"])
                        && (renderChild["originChildren"] = renderChild.children || MergeRoot.emptyArray)
                        && (JSB ? renderChild["_setChildren"](MergeRoot.emptyArray) : (renderChild["_children"] = MergeRoot.emptyArray))
                }
            }
        }

        if (JSB) {
            this.node["_setChildren"](newChildren)
        } else {
            this.node["_children"] = newChildren;
        }
    }

    checkCulling(comp: { getBoundingBox: Function }) {
        return true;
    }

    onAfterDraw() {
        if (!MergeRoot.bMergeItem) {
            return;
        }

        const oldChildren = this.oldChildren;

        const recoverChild = function (node: Node) {
            const originChildren = node["originChildren"] || node.children || MergeRoot.emptyArray;
            if (JSB) {
                node["_setChildren"](originChildren);
            } else {
                node["_children"] = originChildren;
            }
            for (const c of node.children) {
                recoverChild(c);
            }
        }

        for (const c of oldChildren) {
            recoverChild(c);
        }

        if (JSB) {
            this.node["_setChildren"](oldChildren);
        } else {
            this.node["_children"] = oldChildren;
        }

    }

}


